package com.example.consumptionrecords.controller;

import com.aliyun.tea.TeaException;
import com.example.consumptionrecords.config.shiro.PhoneAuthCodeToken;
import com.example.consumptionrecords.config.shiro.RedisSessionDAO;
import com.example.consumptionrecords.entity.dto.LoginUserDTO;
import com.example.consumptionrecords.entity.dto.RegisterUserDTO;
import com.example.consumptionrecords.entity.enums.GlobalConstants;
import com.example.consumptionrecords.entity.enums.SmsTemplateCode;
import com.example.consumptionrecords.entity.http.Response;
import com.example.consumptionrecords.entity.pojo.User;
import com.example.consumptionrecords.entity.vo.UserVO;
import com.example.consumptionrecords.exception.GlobalException;
import com.example.consumptionrecords.exception.UserException;
import com.example.consumptionrecords.service.interfaces.UserService;
import com.example.consumptionrecords.util.random.RandomUtil;
import com.example.consumptionrecords.util.redis.RedisUtil;
import com.example.consumptionrecords.util.sms.SmsUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.crazycake.shiro.SerializeUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

/**
 * 孙敬佳
 * 2024 \ 02 \ 21
 */

@Slf4j
@RestController
@RequestMapping(value = "/user")
public class UserController {

	@Resource
	private UserService userService;

	@Resource
	private RedisUtil redisUtil;

	@Resource
	private SmsUtil smsUtil;

	@PostMapping("/accountPasswordLogin")
	public ResponseEntity<Response<UserVO>> accountPasswordLogin(@RequestBody LoginUserDTO loginUserDTO, HttpServletResponse response) {
		try {
			log.info("用户： {} 使用密码登录", loginUserDTO.getUserName());
			UserVO userVO = userService.userLogin(loginUserDTO, response);
			log.info("用户： {} 登录成功", loginUserDTO.getUserName());
			return ResponseEntity.ok(Response.success("登陆成功", userVO));
		} catch (UnknownAccountException e) {
			log.error("用户：{} 登录出错，没有查找到此用户", loginUserDTO.getUserName());
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_NOT_EXIST.getCode(), e.getMessage()));
		} catch (IncorrectCredentialsException e) {
			log.error("用户：{} 登录出错，密码错误", loginUserDTO.getUserName());
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_PASSWORD_ERR.getCode(), GlobalConstants.USER_PASSWORD_ERR.getMessage()));
		} catch (NullPointerException | GlobalException e) {
			log.error("用户：{} 登录出错", loginUserDTO.getUserName(), e);
			return ResponseEntity.ok(Response.error());
		}
	}

	@PostMapping("/getAuthCode")
	public ResponseEntity<Response<String>> getAuthCode(@RequestBody String phone) {
		try {
			log.info("用户： {} 获取登录验证码", phone);
			String authCode = RandomUtil.getRandomNum(6, false);
			smsUtil.sendSms(phone, authCode, SmsTemplateCode.LOGIN.getCode());
			redisUtil.set(phone, "123456", 60);
			log.info("用户： {} 获取登录验证码成功", phone);
			return ResponseEntity.ok(Response.success("获取验证码成功", "123456"));
		} catch (TeaException e) {
			log.error("用户：{} 获取登录验证码失败{}", phone, e.getMessage(), e);
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_GET_AUTH_CODE.getCode(), GlobalConstants.USER_GET_AUTH_CODE.getMessage()));
		} catch (Exception e) {
			log.error("用户：{} 获取登录验证码失败", phone, e);
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_GET_AUTH_CODE.getCode(), GlobalConstants.USER_GET_AUTH_CODE.getMessage()));
		}
	}

	@PostMapping("/phoneAuthCodeLogin")
	public ResponseEntity<Response<UserVO>> phoneAuthCodeLogin(@RequestBody LoginUserDTO loginUserDTO, HttpServletResponse response) {
		try {
			log.info("用户： {} 使用验证码登录", loginUserDTO.getUserPhone());
			UserVO userVO = userService.userLogin(loginUserDTO, response);
			log.info("用户： {} 登录成功", loginUserDTO.getUserPhone());
			return ResponseEntity.ok(Response.success("登陆成功", userVO));
		} catch (UnknownAccountException e) {
			log.error("用户：{} 登录出错，没有查找到此用户", loginUserDTO.getUserPhone());
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_NOT_EXIST.getCode(), e.getMessage()));
		} catch (IncorrectCredentialsException e) {
			log.error("用户：{} 登录出错，验证码错误", loginUserDTO.getUserPhone());
			return ResponseEntity.ok(Response.error(GlobalConstants.USER_AUTH_CODE_WRONG.getCode(), GlobalConstants.USER_AUTH_CODE_WRONG.getMessage()));
		} catch (UserException e) {
			log.error("用户：{} 登录出错，未获取验证码或已过期", loginUserDTO.getUserPhone());
			return ResponseEntity.ok(Response.error(e.getCode(), e.getMessage()));
		} catch (NullPointerException | GlobalException e) {
			log.error("用户：{} 登录出错", loginUserDTO.getUserPhone(), e);
			return ResponseEntity.ok(Response.error());
		}
	}

	@GetMapping("/unauthorized")
	public ResponseEntity<Response<String>> unauthorized() {
		try {
			log.info("用户未认证访服务");
			return ResponseEntity.ok(Response.error(GlobalConstants.TOKEN_NOT_LOGIN_ERR.getCode(), GlobalConstants.TOKEN_NOT_LOGIN_ERR.getMessage()));
		} catch (NullPointerException | GlobalException e) {
			log.error("证访服务未认证接口出错", e);
			return ResponseEntity.ok(Response.error());
		}
	}

	@GetMapping("/logout")
	public ResponseEntity<Response<String>> logout() {
		Subject subject = SecurityUtils.getSubject();
		User user = (User) subject.getPrincipal();
		log.info("用户：{} 退出登录", user.getUserPhone());
		try {
			if(subject.isAuthenticated()) {
				subject.logout();
			}
			log.info("用户：{} 退出登录成功", user.getUserPhone());
			return ResponseEntity.ok(Response.success());
		} catch (Exception e) {
			log.error("用户：{} 退出登录出错", user.getUserPhone(), e);
			return ResponseEntity.ok(Response.error());
		}
	}

	@PostMapping("/register")
	public ResponseEntity<Response<String>> register(@RequestBody RegisterUserDTO registerUserDTO) {
		try {
			log.info("用户：{} 注册", registerUserDTO.getUserPhone());
			String userName = userService.register(registerUserDTO);
			log.info("用户：{} 户注册成功", registerUserDTO.getUserPhone());
			return ResponseEntity.ok(Response.success(userName));
		} catch (UserException e) {
			log.error("用户：{} 注册失败: {}", registerUserDTO.getUserPhone(), e.getMessage());
			return ResponseEntity.ok(Response.error(e.getCode(), e.getMessage()));
		} catch (Exception e) {
			log.error("用户：{} 注册失败接口出错: ", registerUserDTO.getUserPhone(), e);
			return ResponseEntity.ok(Response.error());
		}
	}

	@GetMapping("/getTotalConsumption")
	public ResponseEntity<Response<String>> getTotalConsumption() {
		User user = (User) SecurityUtils.getSubject().getPrincipal();
		try {
			log.info("用户：{} 查询消费总额", user.getUserPhone());
			String totalConsumption = userService.getTotalConsumption(user.getId());
			log.info("用户：{} 查询消费总额成功", user.getUserPhone());
			return ResponseEntity.ok(Response.success(totalConsumption));
		} catch (Exception e) {
			log.error("用户：{} 查询消费总额出错", user.getUserPhone(), e);
			return ResponseEntity.ok(Response.error());
		}
	}
}
